package com.itheima.aop;


import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.lang.reflect.Array;
import java.util.Arrays;


/**
 * 演示连接点对象 : 可以获取获取目标方法相关的所有信息, 包括方法名、签名、参数、目标类名, 返回值(仅限环绕通知)
 */
@Slf4j
@Aspect  // 生命切片类
@Component // 将本类交给ioc容器进行管理
public class MyAspect5 {


    @Pointcut("execution(* com.itheima.service.DeptService.*(..))")  // 增强被这个注解修饰的方法
    public void pt() {
    }

    @Before("pt()")
    public void before(JoinPoint joinPoint) {
        System.out.println("---------------------------------------------------------------");
        //1.获取目标类名
        String className = joinPoint.getTarget().getClass().getName();
        System.out.println("className = " + className);
        //2.获取目标方法签名
        Signature signature = joinPoint.getSignature();
        System.out.println("signature = " + signature);
        //3.获取目标方法方法名
        String methodName = joinPoint.getSignature().getName();
        System.out.println("methodName = " + methodName);
        //4.获取目标方法原型参数
        Object[] args = joinPoint.getArgs();
        // 这个要转成字符串, 进行打印, 不让就是一个地址值
        System.out.println("args = " + args);
        System.out.println("args = " + Arrays.toString(args));
//        log.info("前置通知...");
        System.out.println("---------------------------------------------------------------");

    }

    //开发中一般是很少用的, 用到就查就可以了
    @Around("pt()")
    public Object after(ProceedingJoinPoint joinPoint) throws Throwable {
        String className = joinPoint.getTarget().getClass().getName(); // 出现重复代码, 所以有这个下划线

        System.out.println("className = " + className);
        //2.获取目标方法签名
        Signature signature = joinPoint.getSignature();
        System.out.println("signature = " + signature);
        //3.获取目标方法方法名
        String methodName = joinPoint.getSignature().getName();
        System.out.println("methodName = " + methodName);
        //4.获取目标方法原型参数
        Object[] args = joinPoint.getArgs();
        // 这个要转成字符串, 进行打印, 不让就是一个地址值
        System.out.println("args = " + args);
        System.out.println("args = " + Arrays.toString(args));
//        log.info("前置通知...");

//        log.info("环绕前通知...");
        //5.获取方法返回值
        Object result = joinPoint.proceed();
        System.out.println("result = " + result);
//        log.info("环绕后通知....");

        return result;
    }


}
